///////  说明  /////
// 带Free RTOS的，需要设置：options for target / Target / Code Generation / arm compiler：V5.06 update 6 或 V5.06 update 7
// 不带Free RTOS的，需设置：options for target / Target / Code Generation / arm compiler：V5.06 update 6 或 V5.06 update 7 或 use default compiler version 6 
// 带系统，需要在Target设置中，添加宏：UsingFreeRTOS
////////// 底板的PCB编号说明 //////////
///// SQDri_WS018       = A型互感器;3.5KW及以下控制器底板。小白盒
///// SQDri_WS018B      = B型互感器;3.5KW及以下控制器底板。小白盒
///// SQDri_EVSEB_7KW   = B型互感器;7KW控制底板。
///// SQDri_EVSEB_11KW  = B型互感器;11KW控制底板。


#ifdef APM32E10X_HD
	#include "apm32e10x_iwdt.h"
#elif defined AT32F403AVGT7
	#include "at32f403a_407_wdt.h"
#else
	#include "apm32f10x_iwdt.h"
#endif

#include "Board.h"
#include "BoardData.h"
// freeRTOS
#ifdef UsingFreeRTOS
#include "BoardTask.h"
#endif

#include "IntTreat.h"  

// 系统时钟设置：
void system_clock_setup(){
	#ifdef AT32F403AVGT7  // 主频设置：
	  crm_reset();
	  //HSE 使能
		crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);    
		while(crm_hext_stable_wait() == ERROR){ }
		// 设置pll参数：
		crm_pll_config(CRM_PLL_SOURCE_HEXT, CM_PLLMF, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
    // 使能PLL
		crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);    
		while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET){		}
    // 配置AHB
		crm_ahb_div_set(CRM_AHB_DIV_1);
    // 配置APB2总线：<= 120MHz;		
		crm_apb2_div_set(CRM_APB2_DIV_2);
    // 配置APB1总线：<= 120MHz;	
		crm_apb1_div_set(CRM_APB1_DIV_2);
    // 打开自主模式：		
		crm_auto_step_mode_enable(TRUE);
    // 将pll作为系统时钟源
		crm_sysclk_switch(CRM_SCLK_PLL);
		while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL){	}
    // 关闭自主模式
		crm_auto_step_mode_enable(FALSE);    
		system_core_clock_update();
  #else
		RCM_Reset();  // 主频设置：120MHz
    RCM_ConfigHSE(RCM_HSE_OPEN);//HSE
    if(RCM_WaitHSEReady() == SUCCESS){
			  RCM_ConfigPLL(RCM_PLLSEL_HSE,CM_PLLMF);// 12M晶振时，设为RCM_PLLMF_8
		    RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
		    RCM_ConfigAHB(RCM_AHB_DIV_1);
		    RCM_ConfigAPB1(RCM_APB_DIV_1);
		    RCM_ConfigAPB2(RCM_APB_DIV_1);
        RCM_EnablePLL(); //使能PLL
        while(RCM_ReadStatusFlag(RCM_FLAG_PLLRDY)== RESET);
		    while(RCM_ReadSYSCLKSource()!= RCM_SYSCLK_SEL_PLL);
	  }		
  #endif
}

// 看门狗初始化：时钟源 = 40KHz
void wdgt_init(){	
	#ifdef AT32F403AVGT7
	  if(crm_flag_get(CRM_WDT_RESET_FLAG) != RESET){
			crm_flag_clear(CRM_WDT_RESET_FLAG); // 重置WDT
		}		
		wdt_register_write_enable(TRUE); 
		wdt_divider_set(WDT_CLK_DIV_4); 
		/* 设置看门狗参数： 
		 timeout = reload_value * (divider / lick_freq ) (s) 
		 lick_freq    = 40000 Hz 
		 divider      = 4 
		 reload_value = 30000 
		 timeout = 10000 * (4 / 40000 ) = 1s = 1000ms 
		*/
		wdt_reload_value_set(30000 - 1);      
		// 喂狗
		wdt_counter_reload();        
		// 看门狗使能
		wdt_enable(); 
	#else	
	  IWDT_EnableWriteAccess(); 
	  // 预分频系数Prer：决定IWDT计数的频率。
	  // 预分频数pr = 4 * 2^Prer; IWDT_DIVIDER_32 的 pr = 32。
    IWDT_ConfigDivider(IWDT_DIVIDER_32); 
	  // 设置重装值rlr：计数超过此值，系统重启。
    IWDT_ConfigReload(50000); 
    IWDT_Enable(); 
	
	  //看门狗重启时间Tout=(pr * rlr) / 40 (ms)
		//IWDT_Refresh(); // 喂狗：
	#endif
}

int main(void){	  
	  system_clock_setup(); 
    SysTick_Config(SystemCoreClock / 1000); // SystemCoreClock =240MHz 
	  #if RCD_Detect == RCD_Detect_POLL
	  NVIC_EnableIRQRequest(SysTick_IRQn, 0, 0);
	  #endif
	  wdgt_init(); 
    Board_init();	
	
	  #if RTC_ON > 0 
		RTC_init();
		#endif
			
	  // 初始化后，开机展示	 
	  #if RTC_ON > 0 
		getTimestampRTC(); 
		#endif
	  led_startUp_TmRecode = system_time;
	    	
	  // 开机事件
	  #if LOG_ON > 0
	  log_temp.occTime  = led_startUp_TmRecode / 1000;
	  log_temp.logGrade = Log_Info;                // 信息级别;
	  log_temp.logEvent = logEvt_StartUP;          // 系统启动;
	  log_temp.logEvtData = system_startup_times;  // 系统是第几次启动;
	  if(log_data_append(log_temp)){
			  writeData[FWD_LogsSize_idx].intData = (uint32_t)Log_Saved_Sum;
				// 数据保存
				flash_write();
				flash_log_write();
		}	  
	  #endif	  
	  
	  #ifdef Using_LedCtrl_74HC595 
	  led_off(BL_PinId); //BL灭 = led_off 
	  Led595_start(led595AllOn);
	  #elif defined Using_LedCtrl_MCUPin 
    led_on(Led_All);
    #endif
	  
	  // 蜂鸣器叫1下
	  #if beep_type == beep_APM || beep_type == beep_BPM 
	  startBeep();
		#elif beep_type == beep_LCD && Using_UART_LCD == LCD_4P3_UART 
		beep_start(1,startBeepTime,startBeepTime);		
	  #endif
		
	  #ifndef	UsingFreeRTOS
	  // 启动等待
	  mTask_SW = mTask_SW | mTask_ledStartUp_bit;	
		#if finger_sensor_type == Finger_HLK_ZW101_EINT
		mTask_SW = mTask_SW | mTask_initStartUp_bit;	
		#endif
	  #endif
		
		
		// 漏电中断开启
		#if RCD_Detect == RCD_Detect_EINT
		leakage_EINT_start();
		#endif
		
		#ifdef SYS_DEBUG
	  printf("   main  %d \r\n",SystemCoreClock);
		printf (" mcu id is 0x%x %x %x\r\n ", MCU_ID_1,MCU_ID_2,MCU_ID_3);
	  #endif
		
		#ifdef UsingFreeRTOS
	  taskInit();		
		#endif
		
		#if Nor_Flash > 0 && defined SYS_DEBUG
		W25Q16_read_DeviceId();
		#endif
		
		#if BleWifi_type == BleWifi_Ai_WB2
		// 测试调试：
		appendArr(bleWiFi_Data.bw_sta_name,wifi_connect_name_def,0,wifi_connect_name_def_len);	
		appendArr(bleWiFi_Data.bw_sta_pwd,wifi_connect_pwd,0,wifi_connect_pwd_size);	
		bleWiFi_Data.bw_reset_step = 1;		
		#endif
    		
    while(1){	
			  #ifdef SYS_DEBUG
			  //printf(" %d ",carD1_get_level()); //读取车载二极管数据；判断硬件是不是有问题。
			  //printf(" %d/%d/%d/%d ", key1_param.keyLevel,key1_level, key1InitLevel, key_get_level());
			  //printf(" %d ",PE_get_level());
			
			  //printf(" %d/%lld/%lld ",PE_get_level(),(system_time - PE_occ_recode),PE_occ_recode);
			
			  //printf(" %d \r\n",ADC_Buffer.ADC_Item.ADCValue_CP);	
						          			
			  #endif
				UpBoard_DisplayUpdate();
			  
    }
}


// 串口复写：
#if using_uart1 > 0 || using_uart2 > 0 || using_uart3 > 0 || using_uart4 > 0 || using_uart5 > 0
int fputc(int ch, FILE *f){
     USART_TxData(print_UART_Id,(char) ch);
     while(USART_ReadStatusFlag(print_UART_Id,USART_FLAG_TXBE) == RESET);
     return(ch);
}
#endif

